package ru.amse.stroganova.ui.tool;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

import ru.amse.stroganova.algorythms.DijkstraAlgorythm;
import ru.amse.stroganova.presentation.VertexPresentation;
import ru.amse.stroganova.ui.GraphComponent;
import ru.amse.stroganova.ui.tool.state.SelectionState;
import ru.amse.stroganova.ui.tool.state.ToolState;

class DijkstraSelectionTool extends Tool {
	
	private final GraphComponent component;
	
	private DijkstraAlgorythm dijkstra;
	
	private ToolState currentState;
	
	private ToolState currentDijkstraState;
	
	private final ToolState startVertexSelectionState = new ToolState() {
		
		@Override
		public void mouseClicked(MouseEvent e) {
			VertexPresentation selectedVertex = component.getGraphElementSelection().getVertex(e.getPoint());
			if (selectedVertex == null) {
				return;
			}
			dijkstra = new DijkstraAlgorythm(component.getGraphPresentation().getGraph(), selectedVertex.getVertex());
			if (dijkstra.hasNegativeWeights()) {
				component.getAlgorythmActionsFactory().meaasgeActive(dijkstra.getErrorMessage(), true);
				return;
			}
			component.getGraphElementMarker().markVertex(selectedVertex);
			component.getGraphElementMarker().markVerticesWithData(dijkstra.getDistances());
			component.getAlgorythmActionsFactory().meaasgeActive("Click on a vertex to see minimal path to it", false);
			currentDijkstraState = pathSelectionState;
		}
	};
	
	private final ToolState pathSelectionState = new ToolState() {
		
		@Override
		public void mouseClicked(MouseEvent e) {
			VertexPresentation selectedVertex = component.getGraphElementSelection().getVertex(e.getPoint());
			if (selectedVertex == null) {
				return;
			}
			component.getGraphElementMarker().unmarkEdges();
			component.getGraphElementMarker().markEdges(dijkstra.getMinimalPathTo(selectedVertex.getVertex()), false);
		}
	};
	
	DijkstraSelectionTool(GraphComponent component) {
		this.component = component;
		currentState = new SelectionState(component, this);
		currentDijkstraState = startVertexSelectionState;
	}
	
	@Override
	public void mousePressed(MouseEvent e) {
		currentState.mousePressed(e);
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		currentDijkstraState.mouseClicked(e);
		currentState.mouseClicked(e);
	}
	
	@Override
	public void mouseDragged(MouseEvent e) {
		currentState.mouseDragged(e);
	}
	
	@Override
	public void mouseReleased(MouseEvent e) {
		currentState.mouseReleased(e);
	}
	
	@Override
	public void setState(ToolState state) {
		currentState = state;
	}
	
	@Override
	public void paint(Graphics g, Color backgroundColor) {
		currentState.paint(g, backgroundColor);
	}
	
	/*package*/ void returnToInitialState() {
		currentState = new SelectionState(component, this);
		currentDijkstraState = startVertexSelectionState;
	}
}
